package com.xmmj.baselibrary.base.activity.lib

import com.xmmj.baselibrary.base.activity.statusbar.StatusBarActivity
import android.os.PowerManager.WakeLock
import android.os.Bundle
import android.os.PowerManager
import com.xmmj.baselibrary.R
import androidx.annotation.IdRes
import android.view.MotionEvent
import android.widget.EditText
import android.os.IBinder
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.fragment.app.Fragment
import java.lang.Exception

/**
 * 该基类的作用：
 * 1.保持/取消屏幕常亮状态
 * 2.隐藏和显示组件
 * 3.Fragment的添加/替换/显示/隐藏操作
 * 4.更多附加基础功能可以写在这里
 */
open class LibBaseActivity : StatusBarActivity() {
    private var wl: WakeLock? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val pm = getSystemService(POWER_SERVICE) as PowerManager

        wl = pm.newWakeLock(
            PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
            resources.getString(R.string.app_name)
        )

        if (isBright()) {
            bright()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (isBright()) {
            cancelBright()
        }
    }

    /**
     * 是否开启常亮
     */
    open fun isBright(): Boolean {
        return true
    }

    /**
     * 屏幕常亮
     */
    fun bright() {
        try {
            wl!!.acquire(0)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 取消常亮
     */
    fun cancelBright() {
        try {
            wl!!.release()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 添加 fragment
     *
     * @param idRes    容器ID
     * @param fragment 待添加的 fragment
     */
    fun addFragment(@IdRes idRes: Int, fragment: Fragment) {
        if (!fragment.isAdded) {
            val ft = supportFragmentManager.beginTransaction()
            ft.add(idRes, fragment)
            ft.commit()
        }
    }

    /**
     * 替换 fragment
     *
     * @param idRes    容器ID
     * @param fragment 待替换的 fragment
     */
    fun replaceFragment(@IdRes idRes: Int, fragment: Fragment?) {
        val ft = supportFragmentManager.beginTransaction()
        ft.replace(idRes, fragment!!)
        ft.commit()
    }

    /**
     * 隐藏 fragment
     *
     * @param fragment 待隐藏的 fragment
     */
    fun hideFragment(fragment: Fragment?) {
        val ft = supportFragmentManager.beginTransaction()
        ft.hide(fragment!!)
        ft.commit()
    }

    /**
     * 显示 fragment
     *
     * @param fragment 待显示的 fragment
     */
    fun showFragment(fragment: Fragment?) {
        val ft = supportFragmentManager.beginTransaction()
        ft.show(fragment!!)
        ft.commit()
    }

    /**
     * 设置当前Fragment
     *
     * @param id       容器id
     * @param fragment 待设置的 fragment
     */
    fun setCurrentFragment(id: Int, fragment: Fragment) {
        val fragments = supportFragmentManager.fragments
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        if (!fragment.isAdded) fragmentTransaction.add(id, fragment, fragment.toString())
        for (i in fragments.indices) {
            val f = fragments[i]
            if (f.tag != fragment.id.toString() + "") fragmentTransaction.hide(f)
        }
        fragmentTransaction.show(fragment)
        fragmentTransaction.commitAllowingStateLoss()
        supportFragmentManager.executePendingTransactions()
    }

    /**
     * 获得当前可视的Fragment
     */
    val visibleFragment: Fragment?
        get() {
            val fragmentManager = supportFragmentManager
            val fragments = fragmentManager.fragments
            for (fragment in fragments) {
                if (fragment != null && fragment.isVisible) return fragment
            }
            return null
        }

    /**
     * 显示试图
     *
     * @param views 视图
     */
    fun visible(vararg views: View) {
        for (view in views) {
            view.visibility = View.VISIBLE
        }
    }

    /**
     * 隐藏视图
     *
     * @param views 视图
     */
    fun invisible(vararg views: View) {
        for (view in views) {
            view.visibility = View.INVISIBLE
        }
    }

    /**
     * 隐藏视图
     *
     * @param views 视图
     */
    fun gone(vararg views: View) {
        for (view in views) {
            view.visibility = View.GONE
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (ev.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus //得到当前页面的焦点,ps:有输入框的页面焦点一般会被输入框占据
            if (isShouldHideKeyboard(v, ev)) { //判断用户点击的是否是输入框以外的区域
                hideKeyboard(v!!.windowToken) //收起键盘
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 是否需要收起输入法
     *
     * @param v     容器
     * @param event 事件
     */
    private fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
        if (v is EditText) { //判断得到的焦点控件是否包含EditText
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            //得到输入框在屏幕中上下左右的位置
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return if (event.x > left && event.x < right && event.y > top && event.y < bottom) {
                //点击位置如果是EditText的区域，忽略它，不收起键盘。
                false
            } else {
                true
            }
        }
        // 如果焦点不是EditText则忽略
        return false
    }

    /**
     * 收起输入法
     *
     * @param token 依赖窗口
     */
    protected fun hideKeyboard(token: IBinder?) {
        if (token != null) {
            val im = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }
}